/**
 * Copyright (c) 2020 libinbin000
 * SFrame is licensed under the Mulan PSL v1.
 * You can use this software according to the terms and conditions of the Mulan PSL v1.
 * You may obtain a copy of Mulan PSL v1 at:
 *     http://license.coscl.org.cn/MulanPSL
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v1 for more details.
 */


import * as WebSocket from "ws";
import {Router} from "../Router";
import {Player} from "./Player";

export class Connect{
    private static connectID:number = 1;
    private static connectNum:number = 0;
    private static connectMap:Map<number, Connect> = new Map(); 

    static create(socket:WebSocket){
        let conn = new Connect(this.connectID++, socket);
        this.connectNum++;
        this.connectMap.set(conn.id, conn);
    }

    static remove(id:number){
        this.connectMap.delete(id);
        this.connectNum--;
    }

    public readonly id:number;
    public readonly socket:WebSocket;
    private isLogin:boolean;
    private player:Player;

    constructor(id:number, socket:WebSocket){
        this.id = id;
        this.socket = socket;

        socket.on("close", this.onClose.bind(this));
        socket.on("error", this.onError.bind(this));
        socket.on("message", this.onMessage.bind(this));
        socket.on("open", this.onOpen.bind(this));

        this.isLogin = false;
    }

    onOpen() {
    }

    onMessage(data: WebSocket.Data) {
        let msg = JSON.parse(data.toString());

        if(!msg || !msg.cmd){
            console.log("协议错误1");
            return;
        }

        //没登录前只能访问 协议号小于100的协议
        if(this.isLogin == true){
            Router.onMessage(msg.cmd, this.player, msg.data);
        }else if(this.isLogin == false && msg.cmd <= 100){
            Router.onMessage(msg.cmd, this, msg.data);
        }else{
            console.log("协议错误", this.isLogin == false, this.isLogin, msg.cmd <= 100)
        }
    }

    onError(err: Error) {
        console.log(err);
    }

    onClose(code: number, reason: string){
        Connect.remove(this.id);
    }

    public send(data:any){
        this.socket.send(data);
    }

    public sendCmd(cmd:number, data:any){
        let msg:any = {};
        msg.cmd = cmd;
        msg.data = data;
        let json = JSON.stringify(msg);
        this.send(json);
    }

    //登陆成功后调用这个方法加载用户数据
    public playerLogin(uid:number, callback:Function){
        Player.getPlayerByID(uid, (player:Player)=>{
            this.isLogin = true;
            this.player = player;
            player.setConnect(this);
            callback();
        });
    }
}